#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
优化的综合评分与排序系统 - 第五步执行模块
专门针对周收益目标(2-3%)设计，优选5只股票
"""

import sys
import os
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')

sys.path.append(os.path.dirname(os.path.abspath(__file__)))

class OptimizedComprehensiveRanking:
    """优化的综合评分与排序系统 - 专为周收益目标设计"""
    
    def __init__(self):
        # 针对周收益目标的权重配置
        self.factor_weights = {
            'weekly_return_expectation': 0.35,  # 周收益预期权重（核心因子）
            'technical_score': 0.30,           # 技术面权重（短期信号）
            'fundamental_score': 0.25,         # 基本面权重（安全保障）
            'risk_reward_ratio': 0.10,         # 风险收益比权重（风险控制）
        }
        
        # 5万资金的仓位管理配置
        self.portfolio_config = {
            'total_capital': 50000,             # 总资金
            'max_single_position': 0.40,       # 单只股票最大仓位40%
            'min_single_position': 0.10,       # 单只股票最小仓位10%
            'cash_reserve': 0.10,              # 现金储备10%
            'target_stocks': 5,                # 目标股票数量
            'rebalance_threshold': 0.05        # 再平衡阈值5%
        }
        
        # 周收益目标风险控制参数
        self.risk_control = {
            'min_expected_return': 0.5,        # 最小周收益预期0.5%
            'max_acceptable_loss': -3.0,       # 最大可接受损失-3%
            'min_success_probability': 0.45,   # 最小成功概率45%
            'max_pe_ratio': 30,                # 最大PE比率
            'min_market_cap': 40,              # 最小市值40亿
        }
        
    def print_header(self, title):
        """打印标题"""
        print(f"\n{'='*80}")
        print(f"🎯 {title}")
        print(f"{'='*80}")
        
    def load_fundamental_results(self, filename="optimized_fundamental_results.csv"):
        """加载基本面分析结果"""
        try:
            df = pd.read_csv(filename)
            print(f"📋 成功加载基本面分析结果: {len(df)} 只股票")
            return df.to_dict('records')
        except Exception as e:
            print(f"❌ 加载基本面分析结果失败: {e}")
            return []
            
    def calculate_weekly_return_score(self, stock_info):
        """计算周收益预期评分"""
        try:
            expected_return = stock_info.get('expected_return', 0)
            success_probability = stock_info.get('success_probability', 0.5)
            max_expected_loss = stock_info.get('max_expected_loss', -2.0)
            
            # 基础收益评分 (0-40分)
            if expected_return >= 3.0:
                return_score = 40
            elif expected_return >= 2.0:
                return_score = 35
            elif expected_return >= 1.5:
                return_score = 30
            elif expected_return >= 1.0:
                return_score = 25
            elif expected_return >= 0.5:
                return_score = 20
            else:
                return_score = 10
                
            # 成功概率评分 (0-35分)
            if success_probability >= 0.70:
                prob_score = 35
            elif success_probability >= 0.60:
                prob_score = 30
            elif success_probability >= 0.50:
                prob_score = 25
            elif success_probability >= 0.45:
                prob_score = 20
            else:
                prob_score = 10
                
            # 风险控制评分 (0-25分)
            if max_expected_loss >= -1.5:
                risk_score = 25
            elif max_expected_loss >= -2.0:
                risk_score = 20
            elif max_expected_loss >= -2.5:
                risk_score = 15
            elif max_expected_loss >= -3.0:
                risk_score = 10
            else:
                risk_score = 5
                
            total_score = return_score + prob_score + risk_score
            return min(100, max(0, total_score))
            
        except Exception as e:
            print(f"   ❌ 计算周收益预期评分失败: {e}")
            return 50
            
    def calculate_risk_reward_score(self, stock_info):
        """计算风险收益比评分"""
        try:
            risk_reward_ratio = stock_info.get('risk_reward_ratio', 0.5)
            
            # 风险收益比评分
            if risk_reward_ratio >= 2.0:
                return 100
            elif risk_reward_ratio >= 1.5:
                return 85
            elif risk_reward_ratio >= 1.0:
                return 70
            elif risk_reward_ratio >= 0.8:
                return 55
            elif risk_reward_ratio >= 0.6:
                return 40
            elif risk_reward_ratio >= 0.4:
                return 25
            else:
                return 10
                
        except Exception as e:
            print(f"   ❌ 计算风险收益比评分失败: {e}")
            return 50
            
    def apply_risk_filters(self, stock_info):
        """应用风险过滤器"""
        try:
            # 检查各项风险控制指标
            risk_issues = []
            
            # 1. 周收益预期检查
            expected_return = stock_info.get('expected_return', 0)
            if expected_return < self.risk_control['min_expected_return']:
                risk_issues.append(f"周收益预期过低({expected_return:.2f}%)")
                
            # 2. 最大损失检查
            max_loss = stock_info.get('max_expected_loss', -2.0)
            if max_loss < self.risk_control['max_acceptable_loss']:
                risk_issues.append(f"最大损失过高({max_loss:.1f}%)")
                
            # 3. 成功概率检查
            success_prob = stock_info.get('success_probability', 0.5)
            if success_prob < self.risk_control['min_success_probability']:
                risk_issues.append(f"成功概率过低({success_prob:.1%})")
                
            # 4. PE比率检查
            pe_ratio = stock_info.get('pe_ratio', 15)
            if pe_ratio > self.risk_control['max_pe_ratio']:
                risk_issues.append(f"PE过高({pe_ratio:.1f})")
                
            # 5. 市值检查
            market_cap = stock_info.get('market_cap', 100)
            if market_cap < self.risk_control['min_market_cap']:
                risk_issues.append(f"市值过小({market_cap:.1f}亿)")
                
            return {
                'pass_filter': len(risk_issues) == 0,
                'risk_issues': risk_issues,
                'risk_count': len(risk_issues)
            }
            
        except Exception as e:
            print(f"   ❌ 风险过滤失败: {e}")
            return {'pass_filter': False, 'risk_issues': ['数据异常'], 'risk_count': 1}
            
    def calculate_comprehensive_score(self, stock_info):
        """计算综合评分"""
        try:
            # 计算各项评分
            weekly_return_score = self.calculate_weekly_return_score(stock_info)
            technical_score = stock_info.get('technical_score', 50)
            fundamental_score = stock_info.get('fundamental_score', 50)
            risk_reward_score = self.calculate_risk_reward_score(stock_info)
            
            # 应用权重计算综合评分
            weights = self.factor_weights
            comprehensive_score = (
                weekly_return_score * weights['weekly_return_expectation'] +
                technical_score * weights['technical_score'] +
                fundamental_score * weights['fundamental_score'] +
                risk_reward_score * weights['risk_reward_ratio']
            )
            
            # 确保评分在合理范围内
            comprehensive_score = max(0, min(100, comprehensive_score))
            
            return {
                'comprehensive_score': round(comprehensive_score, 1),
                'weekly_return_score': round(weekly_return_score, 1),
                'technical_score': round(technical_score, 1),
                'fundamental_score': round(fundamental_score, 1),
                'risk_reward_score': round(risk_reward_score, 1)
            }
            
        except Exception as e:
            print(f"   ❌ 计算综合评分失败: {e}")
            return {
                'comprehensive_score': 50.0,
                'weekly_return_score': 50.0,
                'technical_score': 50.0,
                'fundamental_score': 50.0,
                'risk_reward_score': 50.0
            }
            
    def generate_investment_rating(self, comprehensive_score, stock_info):
        """生成投资评级"""
        try:
            # 基于综合评分的投资评级
            if comprehensive_score >= 85:
                rating = "强烈推荐"
                priority = "高优先级"
                reason = "综合评分优异，周收益预期突出"
            elif comprehensive_score >= 75:
                rating = "推荐"
                priority = "中高优先级"
                reason = "综合表现良好，具备投资价值"
            elif comprehensive_score >= 65:
                rating = "谨慎推荐"
                priority = "中等优先级"
                reason = "综合表现一般，需要谨慎考虑"
            elif comprehensive_score >= 55:
                rating = "观望"
                priority = "低优先级"
                reason = "综合表现偏弱，建议观望"
            else:
                rating = "不推荐"
                priority = "不考虑"
                reason = "综合表现较差，不建议投资"
                
            return {
                'investment_rating': rating,
                'priority_level': priority,
                'rating_reason': reason
            }
            
        except Exception as e:
            print(f"   ❌ 生成投资评级失败: {e}")
            return {
                'investment_rating': '待定',
                'priority_level': '待定',
                'rating_reason': '评级异常'
            }
            
    def analyze_single_stock_comprehensive(self, stock_info):
        """综合分析单只股票"""
        stock_code = stock_info['code']
        stock_name = stock_info['name']
        
        print(f"\n🔍 综合评分: {stock_code} {stock_name}")
        print("-" * 60)
        
        # 应用风险过滤器
        risk_filter = self.apply_risk_filters(stock_info)
        
        # 计算综合评分
        comprehensive_result = self.calculate_comprehensive_score(stock_info)
        
        # 生成投资评级
        rating_result = self.generate_investment_rating(
            comprehensive_result['comprehensive_score'], stock_info
        )
        
        # 显示评分详情
        print(f"   📊 周收益预期评分: {comprehensive_result['weekly_return_score']:.1f}/100")
        print(f"   📈 技术面评分: {comprehensive_result['technical_score']:.1f}/100")
        print(f"   💰 基本面评分: {comprehensive_result['fundamental_score']:.1f}/100")
        print(f"   ⚖️ 风险收益比评分: {comprehensive_result['risk_reward_score']:.1f}/100")
        print(f"   🏆 综合评分: {comprehensive_result['comprehensive_score']:.1f}/100")
        
        # 显示风险过滤结果
        if risk_filter['pass_filter']:
            print(f"   ✅ 风险过滤: 通过")
        else:
            print(f"   ❌ 风险过滤: 未通过")
            print(f"      风险问题: {', '.join(risk_filter['risk_issues'])}")
            
        # 显示投资评级
        print(f"   🎖️ 投资评级: {rating_result['investment_rating']}")
        print(f"   🎯 优先级: {rating_result['priority_level']}")
        print(f"   💡 评级理由: {rating_result['rating_reason']}")
        
        # 显示关键指标
        expected_return = stock_info.get('expected_return', 0)
        success_prob = stock_info.get('success_probability', 0.5)
        max_loss = stock_info.get('max_expected_loss', -2.0)
        pe_ratio = stock_info.get('pe_ratio', 15)
        
        print(f"   📈 周收益预期: {expected_return:.2f}%")
        print(f"   🎯 成功概率: {success_prob:.1%}")
        print(f"   ⚠️ 最大损失: {max_loss:.1f}%")
        print(f"   💵 PE比率: {pe_ratio:.1f}")
        
        # 返回完整结果
        result = {
            **stock_info,
            **comprehensive_result,
            **rating_result,
            **risk_filter
        }
        
        return result
        
    def calculate_portfolio_allocation(self, top_stocks):
        """计算投资组合配置"""
        try:
            total_capital = self.portfolio_config['total_capital']
            cash_reserve = self.portfolio_config['cash_reserve']
            
            # 可投资金额
            investable_amount = total_capital * (1 - cash_reserve)
            
            # 基于综合评分计算权重
            total_score = sum(stock['comprehensive_score'] for stock in top_stocks)
            
            allocations = []
            for stock in top_stocks:
                # 基础权重（基于评分）
                base_weight = stock['comprehensive_score'] / total_score
                
                # 调整权重（考虑风险）
                risk_reward_ratio = stock.get('risk_reward_ratio', 0.5)
                expected_return = stock.get('expected_return', 1.0)
                
                # 风险调整因子
                risk_adjust = min(1.2, max(0.8, risk_reward_ratio))
                return_adjust = min(1.1, max(0.9, expected_return / 2.0))
                
                adjusted_weight = base_weight * risk_adjust * return_adjust
                
                # 应用仓位限制
                max_pos = self.portfolio_config['max_single_position']
                min_pos = self.portfolio_config['min_single_position']
                
                final_weight = max(min_pos, min(max_pos, adjusted_weight))
                
                # 计算具体金额和股数
                allocation_amount = investable_amount * final_weight
                current_price = stock['current_price']
                shares = int(allocation_amount / (current_price * 100)) * 100  # 整手
                actual_amount = shares * current_price
                actual_weight = actual_amount / total_capital
                
                allocation = {
                    'code': stock['code'],
                    'name': stock['name'],
                    'current_price': current_price,
                    'target_weight': final_weight,
                    'allocation_amount': allocation_amount,
                    'shares': shares,
                    'actual_amount': actual_amount,
                    'actual_weight': actual_weight,
                    'expected_return': stock.get('expected_return', 0),
                    'comprehensive_score': stock['comprehensive_score']
                }
                
                allocations.append(allocation)
                
            return allocations
            
        except Exception as e:
            print(f"❌ 计算投资组合配置失败: {e}")
            return []
            
    def run_comprehensive_ranking(self):
        """运行综合评分与排序系统"""
        self.print_header("第五步：综合评分与排序 - 周收益优化版")
        
        print(f"🎯 优化目标: 每周2-3%收益，优选5只股票")
        print(f"💰 资金规模: {self.portfolio_config['total_capital']:,}元")
        print(f"📊 权重配置: 周收益预期({self.factor_weights['weekly_return_expectation']:.0%}) + "
              f"技术面({self.factor_weights['technical_score']:.0%}) + "
              f"基本面({self.factor_weights['fundamental_score']:.0%}) + "
              f"风险收益比({self.factor_weights['risk_reward_ratio']:.0%})")
        
        # 加载基本面分析结果
        fundamental_results = self.load_fundamental_results()
        if not fundamental_results:
            print("❌ 无法加载基本面分析结果，请先执行第四步")
            return []
            
        print(f"\n🔍 开始对 {len(fundamental_results)} 只股票进行综合评分...")
        
        comprehensive_results = []
        
        for i, stock_info in enumerate(fundamental_results, 1):
            print(f"\n[{i:2d}/{len(fundamental_results)}] 综合评分进度")
            
            try:
                result = self.analyze_single_stock_comprehensive(stock_info)
                if result:
                    comprehensive_results.append(result)
            except Exception as e:
                print(f"   ❌ 分析失败: {e}")
                continue
                
        # 按综合评分排序
        comprehensive_results.sort(key=lambda x: x['comprehensive_score'], reverse=True)
        
        # 筛选通过风险过滤的股票
        filtered_results = [r for r in comprehensive_results if r['pass_filter']]
        
        # 生成最终排序报告
        self.generate_final_ranking_report(comprehensive_results, filtered_results)
        
        return comprehensive_results
        
    def generate_final_ranking_report(self, all_results, filtered_results):
        """生成最终排序报告"""
        self.print_header("📊 综合评分排序结果")
        
        print(f"📈 总分析股票数量: {len(all_results)}")
        print(f"✅ 通过风险过滤: {len(filtered_results)}")
        print(f"❌ 未通过风险过滤: {len(all_results) - len(filtered_results)}")
        
        if not filtered_results:
            print("❌ 没有股票通过风险过滤，请调整风险控制参数")
            return
            
        # 统计信息
        avg_score = sum(r['comprehensive_score'] for r in filtered_results) / len(filtered_results)
        avg_return = sum(r['expected_return'] for r in filtered_results) / len(filtered_results)
        avg_success_prob = sum(r['success_probability'] for r in filtered_results) / len(filtered_results)
        
        print(f"📊 平均综合评分: {avg_score:.1f}")
        print(f"📈 平均周收益预期: {avg_return:.2f}%")
        print(f"🎯 平均成功概率: {avg_success_prob:.1%}")
        
        # 投资评级分布
        ratings = {}
        for result in filtered_results:
            rating = result['investment_rating']
            ratings[rating] = ratings.get(rating, 0) + 1
        print(f"🎖️ 投资评级分布: {', '.join([f'{k}({v})' for k, v in ratings.items()])}")
        
        # 显示排序结果
        print(f"\n🏆 综合评分排序（通过风险过滤）:")
        print(f"{'排名':<4} {'代码':<8} {'名称':<10} {'综合':<6} {'周收益':<8} {'成功率':<8} {'评级':<8}")
        print("-" * 75)
        
        for i, result in enumerate(filtered_results[:10], 1):
            expected_return = result['expected_return']
            success_prob = result['success_probability']
            rating = result['investment_rating']
            print(f"{i:<4} {result['code']:<8} {result['name']:<10} "
                  f"{result['comprehensive_score']:<6.1f} {expected_return:<8.2f} "
                  f"{success_prob:<8.1%} {rating:<8}")
                  
        # 优选5只股票
        top5_stocks = filtered_results[:5]
        self.print_header("🎯 最终优选5只股票")
        
        for i, stock in enumerate(top5_stocks, 1):
            print(f"\n🥇 第{i}名: {stock['code']} {stock['name']} ({stock['industry']})")
            print(f"   💯 综合评分: {stock['comprehensive_score']:.1f}/100")
            print(f"   📊 评分构成: 周收益({stock['weekly_return_score']:.1f}) + "
                  f"技术({stock['technical_score']:.1f}) + "
                  f"基本面({stock['fundamental_score']:.1f}) + "
                  f"风险收益比({stock['risk_reward_score']:.1f})")
            print(f"   📈 周收益预期: {stock['expected_return']:.2f}%")
            print(f"   🎯 成功概率: {stock['success_probability']:.1%}")
            print(f"   ⚠️ 最大损失: {stock['max_expected_loss']:.1f}%")
            print(f"   💵 当前价格: ¥{stock['current_price']:.2f}")
            print(f"   🏭 市值: {stock['market_cap']:.1f}亿")
            print(f"   🎖️ 投资评级: {stock['investment_rating']}")
            
        # 投资组合配置
        if len(top5_stocks) >= 3:
            self.print_header("💼 投资组合配置方案")
            
            allocations = self.calculate_portfolio_allocation(top5_stocks)
            
            if allocations:
                total_capital = self.portfolio_config['total_capital']
                cash_reserve_amount = total_capital * self.portfolio_config['cash_reserve']
                
                print(f"💰 总资金: {total_capital:,}元")
                print(f"💵 现金储备: {cash_reserve_amount:,}元 ({self.portfolio_config['cash_reserve']:.0%})")
                print(f"📊 投资分配:")
                
                total_invested = 0
                expected_portfolio_return = 0
                
                for allocation in allocations:
                    print(f"\n   📍 {allocation['code']} {allocation['name']}")
                    print(f"      💰 配置金额: {allocation['actual_amount']:,.0f}元 "
                          f"({allocation['actual_weight']:.1%})")
                    print(f"      📊 购买股数: {allocation['shares']}股")
                    print(f"      💵 买入价格: ¥{allocation['current_price']:.2f}")
                    print(f"      📈 预期周收益: {allocation['expected_return']:.2f}%")
                    
                    total_invested += allocation['actual_amount']
                    expected_portfolio_return += allocation['actual_amount'] * allocation['expected_return'] / 100
                
                actual_cash = total_capital - total_invested
                portfolio_return_rate = expected_portfolio_return / total_capital * 100
                
                print(f"\n📊 投资组合总结:")
                print(f"   💰 总投资金额: {total_invested:,.0f}元")
                print(f"   💵 实际现金余额: {actual_cash:,.0f}元")
                print(f"   📈 组合预期周收益: {portfolio_return_rate:.2f}%")
                print(f"   💡 预期周收益金额: {expected_portfolio_return:,.0f}元")
                
                # 风险提示
                print(f"\n⚠️ 投资风险提示:")
                print(f"   • 以上分析基于历史数据和模型预测，不保证未来收益")
                print(f"   • 股票投资存在亏损风险，请根据个人风险承受能力投资")
                print(f"   • 建议设置止损位，单只股票亏损超过5%时考虑止损")
                print(f"   • 建议定期复盘调整，每周五收盘后重新评估")
                
    def save_final_results(self, comprehensive_results, filename="optimized_final_ranking.csv"):
        """保存最终排序结果"""
        if not comprehensive_results:
            print("❌ 没有分析结果需要保存")
            return None
            
        try:
            # 构建保存数据
            save_data = []
            for i, result in enumerate(comprehensive_results, 1):
                save_record = {
                    'rank': i,
                    'code': result['code'],
                    'name': result['name'],
                    'industry': result['industry'],
                    'current_price': result['current_price'],
                    'market_cap': result['market_cap'],
                    'comprehensive_score': result['comprehensive_score'],
                    'weekly_return_score': result['weekly_return_score'],
                    'technical_score': result['technical_score'],
                    'fundamental_score': result['fundamental_score'],
                    'risk_reward_score': result['risk_reward_score'],
                    'expected_return': result['expected_return'],
                    'success_probability': result['success_probability'],
                    'max_expected_loss': result['max_expected_loss'],
                    'risk_reward_ratio': result['risk_reward_ratio'],
                    'investment_rating': result['investment_rating'],
                    'priority_level': result['priority_level'],
                    'pass_filter': result['pass_filter'],
                    'risk_count': result['risk_count'],
                    'pe_ratio': result['pe_ratio'],
                    'pb_ratio': result['pb_ratio'],
                    'roe': result['roe'],
                    'analysis_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }
                save_data.append(save_record)
                
            df = pd.DataFrame(save_data)
            df.to_csv(filename, index=False, encoding='utf-8-sig')
            print(f"\n💾 最终排序结果已保存到 {filename}")
            return filename
            
        except Exception as e:
            print(f"❌ 保存最终结果失败: {e}")
            return None

if __name__ == "__main__":
    # 创建优化的综合评分系统实例
    ranking_system = OptimizedComprehensiveRanking()
    
    # 执行综合评分与排序
    results = ranking_system.run_comprehensive_ranking()
    
    # 保存结果
    ranking_system.save_final_results(results)
    
    print(f"\n🎉 第五步：优化综合评分与排序执行完成！")
    print(f"   • 成功完成 {len(results)} 只股票的综合评分")
    print(f"   • 已优选出5只最具潜力的投资标的")
    print(f"   • 提供了完整的投资组合配置方案")
    print(f"   • 准备进入第六步：深度分析选中股票")
